package org.nnxy.foodboot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.nnxy.foodboot.entity.User;
import org.nnxy.foodboot.mapper.UserMapper;
import org.nnxy.foodboot.service.UserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.SecretKey;

/**
 * 用户Service实现类
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    @Value("${jwt.secret}")
    private String jwtSecret;
    
    @Value("${jwt.expiration}")
    private Long jwtExpiration;
    
    @Override
    public Map<String, Object> login(String username, String password) {
        try {
            // 查询用户是否存在
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getUsername, username);
            User user = this.getOne(queryWrapper);
            if (user == null) {
                Map<String, Object> result = new HashMap<>();
                result.put("code", 401);
                result.put("message", "用户不存在");
                return result;
            }
            
            // 校验密码
            String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
            if (!encryptedPassword.equals(user.getPassword())) {
                Map<String, Object> result = new HashMap<>();
                result.put("code", 401);
                result.put("message", "密码错误");
                return result;
            }
            
            // 更新最后登录时间
            user.setLastLoginTime(LocalDateTime.now());
            this.updateById(user);
            
            // 生成token
            String token = generateToken(user);
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("code", 200);
            result.put("token", token);
            result.put("data", user);
            result.put("message", "登录成功");
            return result;
        } catch (Exception e) {
            // 统一异常处理
            Map<String, Object> result = new HashMap<>();
            result.put("code", 500);
            result.put("message", "登录失败: " + e.getMessage());
            return result;
        }
    }
    
    @Override
    public boolean register(User user) {
        try {
            // 检查用户名是否已存在
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getUsername, user.getUsername());
            if (this.count(queryWrapper) > 0) {
                throw new RuntimeException("用户名已存在");
            }
            
            // 加密密码
            String encryptedPassword = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
            user.setPassword(encryptedPassword);
            
            // 设置默认值
            user.setStatus(1);
            user.setRole("user"); // 默认为普通用户
            user.setCreateTime(LocalDateTime.now());
            
            // 保存用户
            return this.save(user);
        } catch (Exception e) {
            // 记录异常
            System.err.println("注册用户失败: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 生成JWT token
     */
    private String generateToken(User user) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + jwtExpiration);
        
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());
        claims.put("role", user.getRole());
        
        // 使用配置的jwtSecret来签名JWT
        SecretKey key = Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8));
        
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(user.getUsername())
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(key, SignatureAlgorithm.HS256)
                .compact();
    }
} 